/**
 * @file Arduboy2Core.cpp
 * \brief
 * The Arduboy2Core class for Arduboy hardware initilization and control.
 */

#include "Arduboy2Core.h"



//========================================
//========== class Arduboy2Core ==========
//========================================

Arduboy2Core::Arduboy2Core() { }


void Arduboy2Core::boot() {}


// Pins are set to the proper modes and levels for the specific hardware.
// This routine must be modified if any pins are moved to a different port
void Arduboy2Core::bootPins() {}

void Arduboy2Core::bootOLED() {}

void Arduboy2Core::LCDDataMode() {}

void Arduboy2Core::LCDCommandMode() {}

// Initialize the SPI interface for the display
void Arduboy2Core::bootSPI() {}

// Write to the SPI bus (MOSI pin)
void Arduboy2Core::SPItransfer(uint8_t data) {}

// Write to and read from the SPI bus (out to MOSI pin, in from MISO pin)
uint8_t Arduboy2Core::SPItransferAndRead(uint8_t data)
{
  return 0;
}

void Arduboy2Core::safeMode() {}


/* Power Management */

void Arduboy2Core::idle() {}

void Arduboy2Core::bootPowerSaving() {}

// Shut down the display
void Arduboy2Core::displayOff() {}

// Restart the display after a displayOff()
void Arduboy2Core::displayOn() {}


/* Drawing */

void Arduboy2Core::paint8Pixels(uint8_t pixels)
{

}

void Arduboy2Core::paintScreen(const uint8_t *image)
{

}

// paint from a memory buffer, this should be FAST as it's likely what
// will be used by any buffer based subclass
//
// The following assembly code runs "open loop". It relies on instruction
// execution times to allow time for each byte of data to be clocked out.
// It is specifically tuned for a 16MHz CPU clock and SPI clocking at 8MHz.
void Arduboy2Core::paintScreen(uint8_t image[], bool clear)
{
#define BACKGROUND_COLOR 0xffff /**< Color value for an unlit pixel for draw functions. */
#define FOREGROUND_COLOR 0x0000 /**< Color value for a lit pixel for draw functions. */

    static uint16_t buffer[HEIGHT * WIDTH];

    for(int16_t y = 0; y < HEIGHT; y++)
    {
        for(int16_t x = 0; x < WIDTH; x++ )
        {
            uint8_t row = y / 8;
            uint8_t bit_position = y % 8;
#define IsWhite ((image[(row*WIDTH) + x] & _BV(bit_position)) >> bit_position)
            uint16_t color = IsWhite ? 0xffff : 0x0000;
            buffer[y * WIDTH + x] = color;
        }
    }
  extern void PlatformDrawBitmap(int16_t x0, int16_t y0, int16_t w, int16_t h, uint16_t *data);
  PlatformDrawBitmap(0, 0, WIDTH, HEIGHT, buffer);
}

void Arduboy2Core::blank() {}

void Arduboy2Core::sendLCDCommand(uint8_t command) {}

// invert the display or set to normal
// when inverted, a pixel set to 0 will be on
void Arduboy2Core::invert(bool inverse) {}

// turn all display pixels on, ignoring buffer contents
// or set to normal buffer display
void Arduboy2Core::allPixelsOn(bool on) {}

// flip the display vertically or set to normal
void Arduboy2Core::flipVertical(bool flipped) {}

// flip the display horizontally or set to normal
void Arduboy2Core::flipHorizontal(bool flipped) {}

/* RGB LED */

void Arduboy2Core::setRGBled(uint8_t red, uint8_t green, uint8_t blue) {}

void Arduboy2Core::setRGBled(uint8_t color, uint8_t val) {}

void Arduboy2Core::freeRGBled() {}

void Arduboy2Core::digitalWriteRGB(uint8_t red, uint8_t green, uint8_t blue) {}

void Arduboy2Core::digitalWriteRGB(uint8_t color, uint8_t val) {}

/* Buttons */

uint8_t Arduboy2Core::buttonsState()
{
  uint8_t buttons = 0;

  return buttons;
}

unsigned long Arduboy2Core::generateRandomSeed()
{
  unsigned long seed = 0;


  return seed;
}

// delay in ms with 16 bit duration
void Arduboy2Core::delayShort(uint16_t ms)
{
  delay((unsigned long) ms);
}

void Arduboy2Core::exitToBootloader() {}


//=========================================
//========== class Arduboy2NoUSB ==========
//=========================================

void Arduboy2NoUSB::mainNoUSB() {}

